﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DemoMaskedRider
{
    using Microsoft.Research.Kinect;
    using Microsoft.Research.Kinect.Nui;
    using KINECTUtility;

    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        private Runtime nuiRuntime;
        public Image maskedRider;
        private double maskedRiderWidth;
        private double maskedRiderHeight;
        private AreaChecker myAreaChecker;
        private RuleChecker myRuleChecker;
        private double unitWidth = 40;
        private double unitHeight = 40;

        public MainWindow()
        {
            InitializeComponent();

            maskedRider = this.Resources["MaskedRider"] as Image;
            maskedRider = this.Resources["HeyBrother"] as Image;

            myAreaChecker = new AreaChecker(640, 480, unitWidth, unitHeight);
            myAreaChecker.HoldTime = TimeSpan.FromMilliseconds(5000);
            myAreaChecker.RegistCheckJointID(JointID.HandRight);

            myAreaChecker.AreaMoved += new AreaChecker.AreaCheckerUpdateEventHandler(myAreaChecker_AreaMoved);
            myRuleChecker = new RuleChecker(myAreaChecker);
            myRuleChecker.AddRule(5, 6, RuleDefinition.ActionMode.Occupied);
            myRuleChecker.AddRule(6, 6, RuleDefinition.ActionMode.Occupied);
            myRuleChecker.AddRule(7, 6, RuleDefinition.ActionMode.Occupied);
            myRuleChecker.AddRule(8, 6, RuleDefinition.ActionMode.Occupied);

            myRuleChecker.RuleProgressed += new RuleChecker.AreaRuleCheckerProgressEventHandler(myRuleChecker_RuleProgressed);

            nuiRuntime = new Runtime();
            nuiRuntime.Initialize(RuntimeOptions.UseColor | RuntimeOptions.UseSkeletalTracking | RuntimeOptions.UseDepthAndPlayerIndex);
            nuiRuntime.VideoStream.Open(ImageStreamType.Video, 2, ImageResolution.Resolution640x480, ImageType.Color);

            nuiRuntime.VideoFrameReady += new EventHandler<ImageFrameReadyEventArgs>(nuiRuntime_VideoFrameReady);
            nuiRuntime.SkeletonFrameReady += new EventHandler<SkeletonFrameReadyEventArgs>(nuiRuntime_SkeletonFrameReady);


        }

        void myRuleChecker_RuleProgressed(RuleChecker source, int currentStep)
        {
            string[] ruleChar = { "へ", "ん", "し", "ん" };
            if (currentStep == 0)
            {
                tbRule.Text = "Start:";
            }
            if (!source.IsFailed)
            {
                if (source.IsCompleted)
                {
                    maskedRider.Opacity = 1;
                }
                else
                {
                    tbRule.Text += ruleChar[currentStep];
                }
            }
        }

        void myAreaChecker_AreaMoved(AreaCheckerUpdateEventArgs e)
        {
            tbPosition.Text = String.Format("({0},{1})", e.CurrentIndexHorizontal, e.CurrentIndexVertical);
        }

        private int currentTrackingId=-1;
        void nuiRuntime_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
        {
            if (canvasAR.Children.Count == 0)
            {
                Canvas.SetTop(maskedRider, 0);
                Canvas.SetLeft(maskedRider, 0);
                maskedRider.Opacity = 0;
                this.canvasAR.Children.Add(maskedRider);
            }
            foreach (var data in e.SkeletonFrame.Skeletons)
            {
                if (data.TrackingState == SkeletonTrackingState.Tracked)
                {
                    if (currentTrackingId == -1)
                    {
                        currentTrackingId = data.TrackingID;
                        if (!(cBoxHenshin.IsChecked.Value))
                        {
                            maskedRider.Opacity = 1;
                        }
                    }
                    else
                    {
                        maskedRiderWidth = maskedRider.ActualWidth;
                        maskedRiderHeight = maskedRider.ActualHeight;
                        if (currentTrackingId != data.TrackingID)
                        {
                            currentTrackingId = -1;
                            maskedRider.Opacity = 0;
                        }
                        else
                        {
                            double x = data.Joints[JointID.Head].Position.X;
                            double y = data.Joints[JointID.Head].Position.Y;
                            double z = data.Joints[JointID.Head].Position.Z;

                            double wx = canvasAR.ActualWidth / 2 * (1 + x) - maskedRider.ActualWidth / 2;
                            double wy = canvasAR.ActualHeight / 2 * (1 - y) - maskedRider.ActualHeight / 2;

                            Canvas.SetTop(maskedRider, wy);
                            Canvas.SetLeft(maskedRider, wx);
                        }
                        myAreaChecker.BeginCheck();
                        myAreaChecker.IsIncludePoint(data.Joints[JointID.HandRight].Position.X, data.Joints[JointID.HandRight].Position.Y, JointID.HandRight);
                        myAreaChecker.EndCheck();
                    }
                    break;
                }
            }
        }

        void nuiRuntime_VideoFrameReady(object sender, ImageFrameReadyEventArgs e)
        {
            PlanarImage image = e.ImageFrame.Image;
            imageKinectViewer.Source = BitmapImage.Create(image.Width, image.Height
                , 96, 96, PixelFormats.Bgr32, null, image.Bits, image.Width * image.BytesPerPixel);
        }
    }
}
